home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / dialupip / dialupip2.0 / src / diald / diald.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-14  |  6.8 KB  |  303 lines

  1. /*
  2. **  Copyright (c) 1991 Bolt Beranek and Newman, Inc.
  3. **  All rights reserved.
  4. **
  5. **  Redistribution and use in source and binary forms are permitted
  6. **  provided that: (1) source distributions retain this entire copyright
  7. **  notice and comment, and (2) distributions including binaries display
  8. **  the following acknowledgement:  ``This product includes software
  9. **  developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
  10. **  documentation or other materials provided with the distribution and in
  11. **  all advertising materials mentioning features or use of this software.
  12. **  Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
  13. **  to endorse or promote products derived from this software without
  14. **  specific prior written permission.
  15. **
  16. **  THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17. **  WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18. **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19. */
  20. #include <stdio.h>
  21. #include <signal.h>
  22. #include <errno.h>
  23. #include <setjmp.h>
  24. #include <sys/types.h>
  25. #include <sys/wait.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/time.h>
  28. #include <sys/file.h>
  29. #include <sys/param.h>
  30. #include <netinet/in.h>
  31. #include <netinet/in_systm.h>
  32. #include <netinet/ip.h>
  33. #include <sys/socket.h>
  34. #include <net/if.h>
  35. #include <net/if_du.h>
  36. #include "dialupip.h"
  37. #include "diald.h"
  38.  
  39. typedef struct _TABLE {
  40.     int        Protocol;
  41.     char    *Name;
  42. } TABLE;
  43.  
  44.  
  45. static jmp_buf    context;
  46. static int    pleaserescan;
  47. static int    pleasequit;
  48. static char    *WHERE = "diald";
  49. static TABLE    ProtocolNames[] = {
  50. #ifdef    IPPROTO_IP
  51.     { IPPROTO_IP, "IP Dummy" },
  52. #endif
  53. #ifdef    IPPROTO_ICMP
  54.     { IPPROTO_ICMP, "ICMP" },
  55. #endif
  56. #ifdef    IPPROTO_GGP
  57.     { IPPROTO_GGP, "GGP" },
  58. #endif
  59. #ifdef    IPPROTO_TCP
  60.     { IPPROTO_TCP, "TCP" },
  61. #endif
  62. #ifdef    IPPROTO_EGP
  63.     { IPPROTO_EGP, "EGP" },
  64. #endif
  65. #ifdef    IPPROTO_PUP
  66.     { IPPROTO_PUP, "PUP" },
  67. #endif
  68. #ifdef    IPPROTO_UDP
  69.     { IPPROTO_UDP, "UDP" },
  70. #endif
  71. #ifdef IPPROTO_IDP
  72.     { IPPROTO_IDP, "IDP" },
  73. #endif
  74. #ifdef IPPROTO_RAW
  75.     { IPPROTO_RAW, "RAW" },
  76. #endif
  77.     { 0, NULL }
  78. };
  79.  
  80.  
  81.  
  82. static int
  83. authorized(rp, pkt)
  84.     register REMOTE        *rp;
  85.     register struct du_pkt    *pkt;
  86. {
  87.     register int        i;
  88.     register TABLE        *tp;
  89.     struct timeval        tv;
  90.     struct tm            *tm;
  91.  
  92.     /* check protocol */
  93.     i = pkt->du_ip.ip_p;
  94.     if ((rp->Protocols[P_WORD(i)] & P_BIT(i)) == 0) {
  95.     for (tp = ProtocolNames; tp->Name; tp++)
  96.         if (i == tp->Protocol)
  97.         break;
  98.     d_log(DLOG_INFO, WHERE, "Bad protocol %s (%d)",
  99.         tp ? tp->Name : "unknown");
  100.     return 0;
  101.     }
  102.  
  103.     /* Check time. */
  104.     if (gettimeofday(&tv, (struct timezone *)NULL) < 0) {
  105.     d_log(DLOG_GENERAL, WHERE, "Can't do gettimeofday, %m");
  106.     return 0;
  107.     }
  108.     if ((tm = localtime(&tv.tv_sec)) == NULL) {
  109.     d_log(DLOG_GENERAL, WHERE, "Can't do localtime, %m");
  110.     return 0;
  111.     }
  112.     if ((rp->Times[tm->tm_wday] & (1L << tm->tm_hour)) == 0) {
  113.     d_log(DLOG_INFO, WHERE, "Bad time to call");
  114.     return 0;
  115.     }
  116.  
  117.     /* Check addresses. */
  118.     if (rp->AllowCount && !hostinlist(rp->AllowTo, pkt->du_ip.ip_dst)) {
  119.     d_log(DLOG_INFO, WHERE, "Bad destination address \"%s\"",
  120.         inet_ntoa(pkt->du_ip.ip_dst));
  121.     return 0;
  122.     }
  123.     if (rp->DisallowCount && hostinlist(rp->DisallowFrom, pkt->du_ip.ip_src)) {
  124.     d_log(DLOG_INFO, WHERE, "Bad source address \"%s\"",
  125.         inet_ntoa(pkt->du_ip.ip_src));
  126.     return 0;
  127.     }
  128.  
  129.     /* o.k. to make call */
  130.     return 1;
  131. }
  132.  
  133.  
  134. static void
  135. catchsigterm()
  136. {
  137.     pleasequit++;
  138.     longjmp(context, 1);
  139. }
  140.  
  141.  
  142. static void
  143. catchsighup()
  144. {
  145.     pleaserescan++;
  146.     (void)signal(SIGHUP, catchsighup);
  147.     longjmp(context, 1);
  148. }
  149.  
  150.  
  151. static void
  152. catchsigchld()
  153. {
  154.     union wait    wstatus;
  155.  
  156.     while (wait3(&wstatus, WNOHANG, (struct rusage *)NULL) > 0)
  157.     ;
  158. }
  159.  
  160.  
  161.  
  162. static void
  163. usage()
  164. {
  165.     (void)fprintf(stderr, "usage: %s [options]\n", progname);
  166.     d_log(DLOG_GENERAL, WHERE, "Usage error");
  167.     exit(1);
  168. }
  169.  
  170.  
  171. main(argc, argv)
  172.     int            argc;
  173.     char        *argv[];
  174. {
  175.     int            f;
  176.     int            dofork;
  177.     int            i;
  178.     struct du_pkt    pkt;
  179.     REMOTE        *rp;
  180.     char        buff[256];
  181.     char        *configfile;
  182.  
  183.     /* Set defaults. */
  184.     setprogname(argv[0]);
  185.     WHERE = progname;
  186.     dofork = 1;
  187.     configfile = DIALD_CONFIG;
  188.  
  189.     /* Parse flags. */
  190.     while ((i = getopt(argc, argv, "c:d:F")) != EOF)
  191.     switch (i) {
  192.     default:
  193.         usage();
  194.         /* NOTREACHED */
  195.     case 'c':
  196.         configfile = optarg;
  197.         break;
  198.     case 'd':
  199.         log_level = atoi(optarg);
  200.         break;
  201.     case 'F':
  202.         dofork = 0;
  203.         break;
  204.     }
  205.     argc -= optind;
  206.     argv += optind;
  207.     if (argc)
  208.     usage();
  209.  
  210.     /* Fork us off */
  211.     if (dofork) {
  212.     if ((i = fork()) < 0) {
  213.         d_log(DLOG_GENERAL, WHERE, "Can't fork, %m");
  214.         exit(1);
  215.     }
  216.     if (i > 0)
  217.         exit(0);
  218.     if (freopen("/dev/console", "w", stderr) == NULL)
  219.         d_log(DLOG_GENERAL, WHERE, "Can't set stderr to /dev/console, %m");
  220.     }
  221.  
  222.     /* Read configuration data. */
  223.     if (!readconfig(configfile))
  224.     exit(1);
  225.  
  226.     /* Open the request device. */
  227.     if ((f = open(DEVDIAL, O_RDONLY)) < 0) {
  228.     d_log(DLOG_GENERAL, WHERE, "Can't open \"%s\", %m", DEVDIAL);
  229.     exit(1);
  230.     }
  231. #ifdef    FIOCLEX
  232.     if (ioctl(f, FIOCLEX, (caddr_t)NULL) < 0)
  233.     d_log(DLOG_INFO, WHERE, "Can't do FIOCLEX on \"%s\", %m", DEVDIAL);
  234. #endif    /* FIOCLEX */
  235.  
  236.     /* Tell the log file where are here */
  237.     d_log(DLOG_GENERAL, WHERE, "Diald %s started", dip_release());
  238.     (void)record_pid(progname);
  239.  
  240.     /* Process requests */
  241.     (void)signal(SIGHUP, catchsighup);
  242.     (void)signal(SIGTERM, catchsigterm);
  243.     (void)signal(SIGCHLD, catchsigchld);
  244.     for ( ; ; ) {
  245.     (void)setjmp(context);
  246.     if (pleasequit)
  247.         break;
  248.     if (pleaserescan) {
  249.         d_log(DLOG_GENERAL, WHERE, "Rescanning config files");
  250.         if (!readconfig(configfile)) {
  251.         unlock_pid();
  252.         exit(1);
  253.         }
  254.         (void)signal(SIGHUP, catchsighup);
  255.         pleaserescan = 0;
  256.         continue;
  257.     }
  258.  
  259.     /* Read the device. */
  260.     if ((i = read(f, (char *)&pkt, sizeof pkt)) != sizeof pkt) {
  261.         if (errno != EINTR)
  262.         d_log(DLOG_GENERAL, WHERE,
  263.             "Bad read (%d bytes) from \"%s\", %m",
  264.             i, DEVDIAL);
  265.         continue;
  266.     }
  267.  
  268.     /* Find config data for the address. */
  269.     (void)sprintf(buff, "%s%d", pkt.du_ifname, pkt.du_ifunit);
  270.     if ((rp = findconfig(buff)) == NULL) {
  271.         d_log(DLOG_GENERAL, WHERE, "Address %s not configured",
  272.         inet_ntoa(pkt.du_sin.sin_addr));
  273.         continue;
  274.     }
  275.  
  276.     /* Is this packet is authorized? */
  277.     if (pkt.du_checkit && !authorized(rp, &pkt)) {
  278.         (void)sprintf(buff, "%s not authorized to reach %s",
  279.             inet_ntoa(pkt.du_ip.ip_src), inet_ntoa(pkt.du_ip.ip_dst));
  280.         failcall(rp->Device, buff);
  281.         continue;
  282.     }
  283.  
  284.     /* Make the call. */
  285.     if (!dofork) {
  286.         makecall(rp);
  287.         continue;
  288.     }
  289.     if ((i = fork()) == 0) {
  290.         (void)setpgrp(0, getpgrp(0));
  291.         makecall(rp);
  292.         break;
  293.     }
  294.     if (i < 0)
  295.         d_log(DLOG_GENERAL, WHERE, "Can't fork dialing process, %m");
  296.     }
  297.  
  298.     d_log(DLOG_GENERAL, WHERE, "Diald %s exiting", dip_release());
  299.     unlock_pid();
  300.     exit(0);
  301.     /* NOTREACHED */
  302. }
  303.